export var syn = function (func, onreturn=null) {
	let method = {};
	let it = func.call(func, method);

	let ly;
	let results;
	let count = 0;
	let last = 0;
	let last_result;
	let callback = (index,result) =>{
		count--;
		if(ly.value) {
			results[index] = result;
			if(!count) {
				last = 0;
				ly = it.next(results);
			}
		} else {
			if(last == index) {
				last_result = result;
			}
			if(!count) {
				last = 0;
				ly = it.next(last_result);
			}
		}

		if(onreturn&&ly.done) {
			onreturn(ly.value);
		}
	};

	// 大部分方法都接受相同的命令逻辑
	let adorn = (func) => {
		return (...args)=>{
			let index = count++;
			last = index;
			func(result=>{
                // 调用next方法时需要延迟回调以免迭代结果ly尚未产生
                if(ly) {
                    callback(index, result);
                } else {
                    window.setTimeout(callback, 0, index, result);
                }
			}, ...args);
			return false;
		};
	};
	
	// 返回之前请求的全部值
	method.muti = ()=>{results = new Array(count);return true;};

	// 特别的，如果对多路并发请求需要进行并行处理的，可以调用syn方法‘开启子线程’，但不建议这样使用。
	// syn方法应当配合muti使用
	method.syn = adorn((bk, fun)=>{
		new syn(fun, v=>bk(v));
	});
	// 执行外部方法
	method.exc = (target_func, ...args)=>method.exc_bind(func, target_func, ...args);
	method.exc_bind = adorn((bk, target, target_func, ...args)=>{
		for(let i=1; i<args.length; i++) {
			if(func==args[i]) {
				args[i] = function(as, event){
					bk(as);
				};
			}
		}
		target_func.apply(target, args);
	});
	// 扩展
	method.next = adorn((bk, v)=>{
		bk(v);
	});
	ly = it.next();
	if(ly.done) onreturn(ly.value);
};